JBoss Community Archive (Read Only)

RHQ 4.5

Design - Resource Upgrade

Resource upgrade is meant to provide a means for the plugin developer to be able to touch already inventoried resources and thus provide a way of "upgrading" the resources.

There is a couple of main use cases that drive this effort:

  1. Resource key found not unique - the resource key generation algorithm in the original version of the plugin was later found to be non-unique. For the new corrected version of the plugin to be able to operate on the resource that have already been inventoried, those resources need to have their resource keys upgraded to the corrected format.

  2. "Ugly" resource name - the same type of a problem as with the resource key, only much less crucial. Still from the user POV, this can be quite important.

  3. Structural changes to plugin/resource configuration needed - if the plugin/resource configuration of some resource types is found insufficient, the new version of the plugin should be provided with a way of modifying the actual configuration values from the old-style configuration to the new structure. This is by far the most complicated matter as it would involve changes to the way we store the server-side configuration update history, associated UI updates, etc.

The point 3. has been left out from the implementation for the time being because of the complexity of the required changes and the lack of concrete use cases (or rather use cases that couldn't be handled in another way) that would require this capability.

There is a tracking bugzilla for this https://bugzilla.redhat.com/show_bug.cgi?id=592038

Plugin API changes

Before we dive into the changes in the plugin container, server and other RHQ subsystems, let's first examine the situation from the point of view of the plugin developer. The components the plugin developer creates have no explicit means to examine and traverse the inventory, not to mention to modify it. But the plugin discovery components are responsible for (re)creating the individual resources in the inventory tree. Therefore the best place to insert some additional logic for upgrade would be the discovery components. A standard means of enabling some functionality in the plugin is to provide a facet interface for the plugins to implement, and the resource upgrade is no different:

/**
 * This interface is to be implemented by discovery classes if they want to support
 * upgrading the existing resources to a new format needed by an updated resource component.
 * This is useful for example in the case when a new version of plugin redefined a resource
 * key generation algorithm and wants to upgrade the legacy resources to use the new format.
 *
 * @author Lukas Krejci
 */
public interface ResourceUpgradeFacet<T extends ResourceComponent> {
    /**
     * Specifies what data should change on the provided resource to upgrade it to the current version.
     *
     * @param inventoriedResource a context representing the resource to be upgraded
     * @return a report specifying what aspects of the resource should be changed or null if there is nothing to upgrade
     */
    ResourceUpgradeReport upgrade(ResourceUpgradeContext<T> inventoriedResource);
}

The upgrade() method of this facet is called for every inventoried resource that is determined to be upgraded. The ResourceUpgradeContext<T> class provides the discovery component with all the information about the resource and the component returns a report detailing what should be changed on that resource.

Plugin Container

Where and when

Where is simple - only the plugin has enough information to perform the upgrade. The upgrade must happen as soon as possible during the initialization of the plugin container so that once the plugin container starts fully up, everything is already up-to-date. The ideal spot for upgrade functionality is therefore the InventoryManager.initialize() method that is run very early in the plugin container startup and has enough context already in place to perform the upgrade.

Upgrade Worklow

The agent-side inventory is initialized during the InventoryManager.initialize() method. That method is the place we should invoke the resource upgrade, before any other agent subsystems are started (configuration manager, content manager, etc.) and also before any inventory scan schedulers are started (to prevent their concurrent intervention with the upgrade process).

The upgrade starts with a sync with the server side inventory and then just goes through the synchronized inventory and collects the upgrade requests from individual resources. Once those requests are successfully sent to the server, they are applied on the agent side inventory.

Upgrade Failure Handling

Error recovery during upgrade should be as fine grained as possible. A failure to upgrade one resource shouldn't abort the whole upgrade process or prevent upgrade attempts on other resources even if they are of the same type.

Because our plugin system doesn't support running several versions of the same plugin in parallel (either on agent or server), we can't support rolling back to previous version of the plugin (in that case "similar" resources on different agents could be managed by different versions of the plugins and the server-side code would have make sense of it). The chosen approach is therefore to report the per-resource errors back to the server and stop the resources that failed to upgrade on the agent. At the same time, the discovery of the sibling resources of the failed ones is suspended (for the lifetime of the plugin container) because the discovery could discover a new resource that would be "logically equivalent" to the one that failed and if the user imported that new resource we'd end up in a situation that the whole resource upgrade functionality is trying to solve - duplicate resources that should have been one.

JBoss.org Content Archive (Read Only), exported from JBoss Community Documentation Editor at 2020-03-12 12:38:02 UTC, last content change 2010-10-06 11:31:04 UTC.